package com.liang.cloud.Service.impl;


import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.liang.cloud.Dto.OrderDTO;
import com.liang.cloud.Emun.ResultEnum;
import com.liang.cloud.Exception.SellException;
import com.liang.cloud.Feign.OrderFeign;
import com.liang.cloud.Service.PayService;
import com.liang.cloud.Util.JsonUtil;
import com.liang.cloud.Util.MathUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;

/**
 * @author: 余亮亮
 * @description:
 * @create: 2020-01-05 15:30:59
 **/
@Service
@Slf4j
@Transactional
public class PayServiceImpl implements PayService {

    private static final String ORDER_NAME = "微信点餐订单";

    @Autowired
    private WxPayService wxPayService;

    @Autowired
    private OrderFeign orderFeign;

    @Override
    public WxPayMpOrderResult create(OrderDTO orderDTO) {
        WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
        orderRequest.setBody(ORDER_NAME);
        orderRequest.setOutTradeNo(orderDTO.getOrderId());
        orderRequest.setTotalFee(BaseWxPayRequest.yuanToFen(orderDTO.getOrderAmount().toString()));//元转成分
        orderRequest.setOpenid(orderDTO.getBuyerOpenid());
        orderRequest.setSpbillCreateIp("8.8.8.8");
//        orderRequest.setTimeStart("yyyyMMddHHmmss");
//        orderRequest.setTimeExpire("yyyyMMddHHmmss");

        //返回值为{com.github.binarywang.wxpay.bean.order}包下的类
        WxPayMpOrderResult result = null;
        try {
            result = wxPayService.createOrder(orderRequest);
        } catch (WxPayException e) {
            log.error("【微信支付】发起支付错误,原因{}",e.getMessage());
            throw new SellException(ResultEnum.WECHAT_MA_PAY_ERROR.getCode(),e.getMessage());
        }
//
        return result;
    }

    @Override
    public WxPayOrderNotifyResult notify(String notifyData) {
        //1. 验证签名
        //2. 支付的状态
        //3. 支付金额
        //4. 支付人(下单人 == 支付人)
        WxPayOrderNotifyResult  result = new WxPayOrderNotifyResult();
        try {
            result = wxPayService.parseOrderNotifyResult(notifyData);
            log.info("【微信支付】异步通知, payResponse={}", JsonUtil.toJson(result));
        } catch (WxPayException e) {
            e.printStackTrace();
        }


        //查询订单
        OrderDTO orderDTO = orderFeign.findOne(result.getOutTradeNo());

        //判断订单是否存在
        if (orderDTO == null) {
            log.error("【微信支付】异步通知, 订单不存在, orderId={}", result.getOutTradeNo());
            throw new SellException(ResultEnum.ORDER_NOT_EXIST);
        }

        //判断金额是否一致(0.10   0.1)
        if (!MathUtil.equals(new Double(BaseWxPayResult.fenToYuan(result.getTotalFee())), orderDTO.getOrderAmount().doubleValue())) {
            log.error("【微信支付】异步通知, 订单金额不一致, orderId={}, 微信通知金额={}, 系统金额={}",
                    result.getOutTradeNo(),
                    BaseWxPayResult.fenToYuan(result.getTotalFee()),
                    orderDTO.getOrderAmount());
            throw new SellException(ResultEnum.WXPAY_NOTIFY_MONEY_VERIFY_ERROR);
        }

        //修改订单的支付状态
        orderFeign.paid(orderDTO);

        return result;
    }

    @Override
    public WxPayRefundResult refund(OrderDTO orderDTO) {

        WxPayRefundRequest request = new WxPayRefundRequest();
        request.setOutTradeNo(orderDTO.getOrderId());
        request.setTotalFee(orderDTO.getOrderAmount().intValue());
        request.setRefundFee(orderDTO.getOrderAmount().intValue());
        WxPayRefundResult result = new WxPayRefundResult();
        try {
                result = wxPayService.refund(request);
        } catch (WxPayException e) {
            log.error("退款有误：{}",e.getReturnMsg());
        }
        return result;
    }
}
